package com.deimos.sps;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.vast.ows.GetCapabilitiesRequest;
import org.vast.ows.OWSException;

import org.vast.ows.sps.SPSUtils;
import com.deimos.dataBase.Sensor;

public class GetCapabilitiesServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    /**
     * So far this Servlet just is implemented in order to show what is expected
     * to return the GetCapabilities service. As soon is define the schema of
     * the Xml GetCapabilities response it will be updated
     * 
     * @param req
     * @param res
     */
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
	Date start = new Date();
	String queryString = req.getQueryString();

	try {
	    /*
	     * Due to a bug in the library. The GetCapabilities call has changed
	     * in OWS Common 1.1 and the changes are not yet reflected in the
	     * library. If you want the right behaviour, you can however simply
	     * not use the library for this operation since it is very simple to
	     * parse.
	     */
	    if ((queryString.toLowerCase().contains("service=sps") && queryString.toLowerCase().contains("request=getcapabilities")) || (queryString.toLowerCase().contains("service=sps") && queryString.toLowerCase().contains("request=getcapabilities") && queryString.toLowerCase().contains("version=2.0"))) {
		this.GetCapabilities(req, res);
	    } else {
		PrintWriter out = res.getWriter();
		out.println("Http parameters not correct");
		out.close();

		throw new java.io.IOException("Http parameters not correct " + this.getClass().getName());
	    }
	} catch (Exception e) {
	    e.printStackTrace();
	}
	System.out.println("Execution time: " + ((new Date()).getTime() - start.getTime()));
    }

    private void GetCapabilities(HttpServletRequest req, HttpServletResponse res) throws OWSException {
	PrintWriter out = null;
	SPSUtils utils = new SPSUtils();
	String address = req.getRequestURL().toString().replace("GetCapabilitiesServlet", "") + "services/HMA-SPS";
	String service = null;
	try {
	    GetCapabilitiesRequest request = (GetCapabilitiesRequest) utils.readURLQuery(req.getQueryString(), "SPS", "2.0");

	    if (request.getService().equals("SPS"))
		service = request.getService();

	    out = res.getWriter();
	    out.println("<?xml version=" + '"' + "1.0" + '"' + " encoding=" + '"' + "UTF-8" + '"' + "?>");
	    out.println("<sps:Capabilities " + "version=\"2.0.0\" " + "xsi:schemaLocation=\"http://www.w3.org/2003/05/soap-envelope http://www.w3.org/2003/05/soap-envelope/soap-envelope.xsd http://www.opengis.net/sps/2.0 http://schemas.opengis.net/sps/2.0.0/sps.xsd http://www.w3.org/2005/08/addressing http://www.w3.org/2005/08/addressing/ws-addr.xsd\" " + "xmlns:sps=\"http://www.opengis.net/sps/2.0\" " + "xmlns:xlink=\"http://www.w3.org/1999/xlink\" " + "xmlns:wsa=\"http://www.w3.org/2005/08/addressing\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + "xmlns:ows=\"http://www.opengis.net/ows/1.1\" " + "xmlns:gml=\"http://www.opengis.net/gml/3.2\" " + "xmlns:swes=\"http://www.opengis.net/swes/2.0\" " + "xmlns:wstop=\"http://docs.oasis-open.org/wsn/t-1\"" + ">");
	    out.println("<ows:ServiceIdentification>");
	    out.println("   <ows:Title>HMA-FO Sensor Planning Service I/F</ows:Title>");
	    out.println("   <ows:Abstract>HMA-FO sps developed by Deimos-Space</ows:Abstract>");
	    out.println("   <ows:ServiceType>" + service + "</ows:ServiceType>");
	    out.println("   <ows:ServiceTypeVersion>" + "2.0.0" + "</ows:ServiceTypeVersion>");
	    out.println("   <ows:Fees>none</ows:Fees>");
	    out.println("   <ows:AccessConstraints>none</ows:AccessConstraints>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SPS/2.0/conf/BasicPubSub</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SPS/2.0/conf/ChannelBasedPubSub</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SPS/2.0/conf/Core</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SPS/2.0/conf/FeasibilityController</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SPS/2.0/conf/ReservationManager</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SPS/2.0/conf/SOAP</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SPS/2.0/conf/StateLogger</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SPS/2.0/conf/TaskCanceller</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SPS/2.0/conf/TaskUpdater</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SPS/2.0/conf/XMLEncoding</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWES/2.0/conf/BasicSWEServiceMetadata</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWES/2.0/conf/SensorProvider</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWES/2.0/conf/SensorHistoryProvider</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWES/2.0/conf/XMLEncoding</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWES/2.0/conf/SOAPBinding</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWES/2.0/conf/PublishSubscribe</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWE/2.0/conf/core</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWE/2.0/conf/uml-simple-components</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWE/2.0/conf/uml-record-components</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWE/2.0/conf/uml-choice-components</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWE/2.0/conf/uml-simple-encodings</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWE/2.0/conf/xsd-simple-components</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWE/2.0/conf/xsd-record-components</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWE/2.0/conf/xsd-choice-components</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWE/2.0/conf/xsd-simple-encodings</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWE/2.0/conf/general-encoding-rules</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/SWE/2.0/conf/text-encoding-rules</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/EOSPS/2.0/conf/core/feasibility-level-default</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/EOSPS/2.0/conf/core/tasking-params-valid</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/EOSPS/2.0/conf/core/tasking-params-xml-encoding</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/EOSPS/2.0/conf/core/priority-default</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/EOSPS/2.0/conf/core/survey-period-mandatory</ows:Profile>");
	    out.println("   <ows:Profile>http://www.opengis.net/spec/EOSPS/2.0/conf/core/time-series-coherent</ows:Profile>");
	    out.println("</ows:ServiceIdentification>");
	    out.println("<ows:OperationsMetadata>");
	    out.println("   <ows:Operation name=" + '"' + "DescribeTasking" + '"' + ">");
	    out.println("      <ows:DCP>");
	    out.println("    	  <ows:HTTP>");
	    out.println("            <ows:Get xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("            <ows:Post xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("         </ows:HTTP>");
	    out.println("      </ows:DCP>");
	    out.println("   </ows:Operation>");
	    out.println("   <ows:Operation name=" + '"' + "GetFeasibility" + '"' + ">");
	    out.println("      <ows:DCP>");
	    out.println("         <ows:HTTP>");
	    out.println("            <ows:Get xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("            <ows:Post xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("         </ows:HTTP>");
	    out.println("      </ows:DCP>");
	    out.println("   </ows:Operation>");
	    out.println("   <ows:Operation name=" + '"' + "Submit" + '"' + ">");
	    out.println("      <ows:DCP>");
	    out.println("    	  <ows:HTTP>");
	    out.println("            <ows:Get xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("            <ows:Post xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("    	  </ows:HTTP>");
	    out.println("      </ows:DCP>");
	    out.println("   </ows:Operation>");
	    out.println("   <ows:Operation name=" + '"' + "GetStatus" + '"' + ">");
	    out.println("      <ows:DCP>");
	    out.println("    	  <ows:HTTP>");
	    out.println("            <ows:Get xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("            <ows:Post xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("    	  </ows:HTTP>");
	    out.println("      </ows:DCP>");
	    out.println("   </ows:Operation>");
	    out.println("   <ows:Operation name=" + '"' + "DescribeResultAccess" + '"' + ">");
	    out.println("      <ows:DCP>");
	    out.println("    	  <ows:HTTP>");
	    out.println("            <ows:Get xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("            <ows:Post xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("    	  </ows:HTTP>");
	    out.println("      </ows:DCP>");
	    out.println("   </ows:Operation>");
	    out.println("   <ows:Operation name=" + '"' + "Cancel" + '"' + ">");
	    out.println("      <ows:DCP>");
	    out.println("    	  <ows:HTTP>");
	    out.println("            <ows:Get xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("            <ows:Post xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("    	  </ows:HTTP>");
	    out.println("      </ows:DCP>");
	    out.println("   </ows:Operation>");
	    out.println("   <ows:Operation name=" + '"' + "Reserve" + '"' + ">");
	    out.println("      <ows:DCP>");
	    out.println("         <ows:HTTP>");
	    out.println("            <ows:Get xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("            <ows:Post xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("    	  </ows:HTTP>");
	    out.println("      </ows:DCP>");
	    out.println("   </ows:Operation>");
	    out.println("   <ows:Operation name=" + '"' + "Confirm" + '"' + ">");
	    out.println("      <ows:DCP>");
	    out.println("    	  <ows:HTTP>");
	    out.println("            <ows:Get xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("            <ows:Post xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("    	  </ows:HTTP>");
	    out.println("      </ows:DCP>");
	    out.println("   </ows:Operation>");
	    out.println("   <ows:Operation name=" + '"' + "Validate" + '"' + ">");
	    out.println("      <ows:DCP>");
	    out.println("    	  <ows:HTTP>");
	    out.println("            <ows:Get xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("            <ows:Post xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("    	  </ows:HTTP>");
	    out.println("      </ows:DCP>");
	    out.println("   </ows:Operation>");
	    out.println("   <ows:Operation name=" + '"' + "GetSensorAvailability" + '"' + ">");
	    out.println("      <ows:DCP>");
	    out.println("         <ows:HTTP>");
	    out.println("            <ows:Get xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("            <ows:Post xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("    	  </ows:HTTP>");
	    out.println("      </ows:DCP>");
	    out.println("   </ows:Operation>");
	    out.println("   <ows:Operation name=" + '"' + "Subscribe" + '"' + ">");
	    out.println("      <ows:DCP>");
	    out.println("    	  <ows:HTTP>");
	    out.println("            <ows:Get xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("            <ows:Post xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("    	  </ows:HTTP>");
	    out.println("      </ows:DCP>");
	    out.println("   </ows:Operation>");
	    out.println("   <ows:Operation name=" + '"' + "DescribeSensor" + '"' + ">");
	    out.println("      <ows:DCP>");
	    out.println("         <ows:HTTP>");
	    out.println("            <ows:Get xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("            <ows:Post xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("         </ows:HTTP>");
	    out.println("      </ows:DCP>");
	    out.println("   </ows:Operation>");
	    out.println("   <ows:Operation name=" + '"' + "SubmitSegmentByID" + '"' + ">");
	    out.println("      <ows:DCP>");
	    out.println("         <ows:HTTP>");
	    out.println("            <ows:Get xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("            <ows:Post xlink:href=" + '"' + address + '"' + " xlink:type=" + '"' + "simple" + '"' + "/>");
	    out.println("         </ows:HTTP>");
	    out.println("      </ows:DCP>");
	    out.println("   </ows:Operation>");
	    out.println("</ows:OperationsMetadata>");
	    out.println("<sps:notifications>");
	    out.println("   <swes:NotificationProducerMetadata>");
	    out.println("      <swes:producerEndpoint xmlns:wsa=\"http://www.w3.org/2005/08/addressing\">");
	    out.println("         <wsa:EndpointReference>");
	    out.println("             <wsa:Address>" + address + "</wsa:Address>");
	    out.println("         </wsa:EndpointReference>");
	    out.println("      </swes:producerEndpoint>");
	    out.println("      <swes:supportedDialects>");
	    out.println("          <swes:FilterDialectMetadata>");
	    out.println("              <swes:topicExpressionDialect>http://docs.oasis-open.org/wsn/t-1/TopicExpression/Simple</swes:topicExpressionDialect>");
	    out.println("              <swes:topicExpressionDialect>http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete</swes:topicExpressionDialect>");
	    out.println("              <swes:messageContentDialect>http://www.w3.org/TR/1999/REC-xpath-19991116</swes:messageContentDialect>");
	    out.println("          </swes:FilterDialectMetadata>");
	    out.println("      </swes:supportedDialects>");
	    out.println("      <swes:fixedTopicSet>true</swes:fixedTopicSet>");
	    out.println("      <swes:servedTopics>");
	    out.println("         <wstop:TopicSet xmlns:wstop=\"http://docs.oasis-open.org/wsn/t-1\" xmlns:eo=\"http://www.opengis.net/eosps/2.0\">");
	    out.println("            <sps:TaskEvent>");
	    out.println("               <sps:TaskFailure wstop:topic=\"true\" />");
	    out.println("               <sps:TaskCancellation wstop:topic=\"true\" />");
	    out.println("               <sps:TaskCompletion wstop:topic=\"true\" />");
	    out.println("               <sps:TaskUpdate wstop:topic=\"true\" />");
	    out.println("               <sps:DataPublication wstop:topic=\"true\" />");
	    out.println("               <sps:TaskSubmission wstop:topic=\"true\" />");
	    out.println("            </sps:TaskEvent>");
	    out.println("            <sps:TaskingRequestEvent>");
	    out.println("               <sps:TaskingRequestAcceptance wstop:topic=\"true\" />");
	    out.println("               <sps:TaskingRequestRejection wstop:topic=\"true\" />");
	    out.println("            </sps:TaskingRequestEvent>");
	    out.println("            <eo:EOEvent>");
	    out.println("               <eo:SegmentPlanned wstop:topic=\"true\" />");
	    out.println("               <eo:SegmentAcquired wstop:topic=\"true\" />");
	    out.println("               <eo:SegmentValidated wstop:topic=\"true\" />");
	    out.println("               <eo:SegmentCancelled wstop:topic=\"true\" />");
	    out.println("               <eo:SegmentFailed wstop:topic=\"true\" />");
	    out.println("            </eo:EOEvent>");
	    out.println("         </wstop:TopicSet>");
	    out.println("      </swes:servedTopics>");
	    out.println("   </swes:NotificationProducerMetadata>");
	    out.println("</sps:notifications>");

	    if (Sensor.getAllSensor().size() != 0) {

		out.println("<sps:contents>");
		out.println("   <sps:SPSContents>");
		out.println("      <swes:procedureDescriptionFormat>http://www.opengis.net/sensorML/1.0</swes:procedureDescriptionFormat>");
		out.println("      <swes:observableProperty>http://sweet.jpl.nasa.gov/2.0/physRadiation.owl#Radiance</swes:observableProperty>");
		int i = 0;
		for (Sensor sensor : Sensor.getAllSensor()) {
		    out.println("      <swes:offering>");
		    out.println("         <sps:SensorOffering>");
		    out.println("		<swes:description>Programming service for " + sensor.instrumentName + " only</swes:description>");
		    out.println("		<swes:identifier>" + sensor.instrumentName + "</swes:identifier>");
		    out.println("		<swes:extension>");
		    out.println("		</swes:extension>");
		    out.println("		<swes:procedure>" + sensor.id + "</swes:procedure>");
		    out.println("		<sps:observableArea>");
		    out.println("		   <sps:byPolygon>");
		    out.println("		      <gml:Polygon gml:id=\"gid" + i + "\">");
		    out.println("		         <gml:exterior>");
		    out.println("		            <gml:LinearRing>");
		    out.println("		               <gml:posList srsName=\"urn:ogc:def:crs:EPSG:6.17:4326\">-180 -80 +180 -80 +180 +80 -180 +80</gml:posList>");
		    out.println("		             </gml:LinearRing>");
		    out.println("		           </gml:exterior>");
		    out.println("		      </gml:Polygon>");
		    out.println("		   </sps:byPolygon>");
		    out.println("		</sps:observableArea>");
		    out.println("         </sps:SensorOffering>");
		    out.println("      </swes:offering>");
		    i++;
		}
		out.println("      <sps:minStatusTime>PT48H</sps:minStatusTime>");
		out.println("      <sps:supportedEncoding>http://www.opengis.net/swe/2.0/TextEncoding</sps:supportedEncoding>");
		out.println("      <sps:supportedEncoding>http://www.opengis.net/swe/2.0/XMLEncoding</sps:supportedEncoding>");

		out.println("   </sps:SPSContents>");
		out.println("</sps:contents>");
	    }
	    out.println("</sps:Capabilities>");
	    out.close();

	} catch (IOException e) {
	    e.printStackTrace();
	}
    }
}
